package semantic;

import java.util.ArrayList;
import java.util.Stack;

import parser.Parser;
import common.BasicId;
import common.Enum;
import common.Enum.idKind;
import common.Enum.innerType;
import common.InnerArrayType;
import common.InnerBasicType;
import common.InnerRecordType;
import common.ProcId;
import common.InnerRecordType.fieldChain;
import common.InnerType;
import common.SpecId;
import common.TreeNode;
import common.VarId;

/**
 * 语义分析
 * 
 * @author Administrator
 *
 */
public class SemanticAnalysis {
	private ArrayList<BasicId> idTable; // 全局符号表
	private Stack<Integer> scopeStack; // 分割局部化区域的栈
	private int level = 0; // 层数
	private int offset = 0; // 偏移
	private int roff = 0;// 记录的偏移

	public SemanticAnalysis() {
		idTable = new ArrayList<BasicId>();
		scopeStack = new Stack<Integer>();
	}

	public void Program(TreeNode root) {
		if (root.getNonTerminal().equals(Enum.nonTerminals.Program)) {
			DeclarePart(root.getChild(1));
			ProgramBody(root.getChild(2));
		}
	}

	private void ProgramBody(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.ProgramBody)) {
			StmList(child.getChild(1));
			// 退出局部化区域处理
			level--;
			// 新建一个特殊节点
			BasicId bi = new SpecId();
			bi.kind = Enum.idKind.specKind;
			bi.line = scopeStack.pop();
			idTable.add(bi);

		}

	}

	private void StmList(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.StmList)) {
			Stm(child.getChild(0));
			StmMore(child.getChild(1));
		}
	}

	private void StmMore(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.StmMore)) {
			if (child.getchildNum() > 0) {
				StmList(child.getChild(1));
			}
		}

	}

	private void Stm(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.Stm)) {
			if (child.getChild(0).getchildNum() == 0) {
				// ID AssCall
				// 标识符的引用

				BasicId bi = searchInnerType(child.getChild(0));
				AssCall(child.getChild(1), bi);

			} else if (child.getChild(0).getNonTerminal()
					.equals(Enum.nonTerminals.ConditionalStm)) {
				ConditionalStm(child.getChild(0));
			} else if (child.getChild(0).getNonTerminal()
					.equals(Enum.nonTerminals.LoopStm)) {
				LoopStm(child.getChild(0));
			} else if (child.getChild(0).getNonTerminal()
					.equals(Enum.nonTerminals.InputStm)) {
				InputStm(child.getChild(0));
			} else if (child.getChild(0).getNonTerminal()
					.equals(Enum.nonTerminals.OutputStm)) {
				OutputStm(child.getChild(0));
			} else {
				// return 语句
			}
		}

	}

	private void AssCall(TreeNode child, BasicId bi) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.AssCall)) {
			if (child.getChild(0).getNonTerminal()
					.equals(Enum.nonTerminals.AssignmentRest)) {
				AssignmentRest(child.getChild(0), bi);
			} else {
				CallStmRest(child.getChild(0), bi);
			}
		}

	}

	private void CallStmRest(TreeNode child, BasicId bi) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.CallStmRest)) {
			if (bi.kind.equals(Enum.idKind.procKind)) {
				// 获取参数列表
				ProcId pi = (ProcId) bi;
				ArrayList<Enum.innerType> paramTypeList = new ArrayList<Enum.innerType>();
				ActParamList(child.getChild(1), paramTypeList);

				if (pi.paramCount == paramTypeList.size()) {
					for (int i = 1; i <= pi.paramCount; i++) {
						if (idTable.get(i + pi.paramStart).itype.kind
								.equals(paramTypeList.get(i - 1))) {
							continue;
						} else {
							
							//System.out.println();
							
							common.Error.setError(child.getChild(0).getLine(),
									0, 3);
							common.Error.printError("参数类型不匹配");
						}
					}
				} else {
					common.Error.setError(child.getChild(0).getLine(), 0, 3);
					common.Error.printError("参数个数不匹配");
				}
			} else {
				common.Error.setError(child.getChild(0).getLine(), 0, 3);
				common.Error.printError(bi.data + "不是过程名");
			}
		}

	}

	private void ActParamList(TreeNode child, ArrayList<innerType> paramTypeList) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.ActParamList)) {
			if (child.getchildNum() > 0) {
				paramTypeList.add(Exp(child.getChild(0)));
				ActParamMore(child.getChild(1), paramTypeList);
			}
		}

	}

	private void ActParamMore(TreeNode child, ArrayList<innerType> paramTypeList) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.ActParamMore)) {
			if (child.getchildNum() > 0) {
				ActParamList(child.getChild(1), paramTypeList);
			}
		}

	}

	private void AssignmentRest(TreeNode child, BasicId bi) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.AssignmentRest)) {
			if (bi.kind.equals(Enum.idKind.varKind)) {

				if (child.getChild(0).getchildNum() > 0) {

					if (!VariMore(child.getChild(0), bi).equals(
							Exp(child.getChild(2)))) {
						common.Error
								.setError(child.getChild(1).getLine(), 0, 3);
						common.Error.printError("类型不相容");
					}
				} else {
					if (bi.kind.equals(Enum.idKind.varKind)) {
						if (!bi.itype.kind.equals(Exp(child.getChild(2)))) {
							common.Error.setError(child.getChild(1).getLine(),
									0, 3);
							common.Error.printError("类型不相容");
						}
					} else {
						// System.out.println("kind=="+ bi.kind);
						common.Error
								.setError(child.getChild(1).getLine(), 0, 3);
						common.Error.printError(bi.data + "不是变量");
					}

				}
			} else {
				common.Error.setError(child.getChild(1).getLine(), 0, 3);
				common.Error.printError(bi.data + "不是变量类型");
			}

		}

	}

	private void OutputStm(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.OutputStm)) {
			Exp(child.getChild(2));
		}
	}

	private void InputStm(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.InputStm)) {
			Invar(child.getChild(2));
		}

	}

	private void Invar(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.Invar)) {
			searchInnerType(child.getChild(0));
		}
	}

	private void LoopStm(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.LoopStm)) {
			boolean b = RelExp(child.getChild(1));

			if (b) {
				StmList(child.getChild(3));
			} else {
				common.Error.setError(child.getChild(0).getLine(), 0, 3);
				common.Error.printError("不是条件表达式");
			}
		}
	}

	private void ConditionalStm(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.ConditionalStm)) {
			boolean b = RelExp(child.getChild(1));

			if (b) {
				StmList(child.getChild(3));
				StmList(child.getChild(5));
			} else {
				common.Error.setError(child.getChild(0).getLine(), 0, 3);
				common.Error.printError("不是条件表达式");
			}

		}
	}

	private boolean RelExp(TreeNode child) {

		if (child.getNonTerminal().equals(Enum.nonTerminals.RelExp)) {
			Enum.innerType it = Exp(child.getChild(0));
			return OtherRelE(child.getChild(1), it);
		}
		return false;
	}

	private boolean OtherRelE(TreeNode child, innerType it) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.OtherRelE)) {
			if (it.equals(Enum.innerType.IntType)
					|| it.equals(Enum.innerType.CharType)) {
				if (it.equals(Exp(child.getChild(1)))) {
					return true;
				} else {
					common.Error.setError(child.getChild(0).getChild(0)
							.getLine(), 0, 3);
					common.Error.printError("类型不相容");
				}
			} else {
				// 其他类型不能做比较
				return false;
			}
		}
		return false;
	}

	private Enum.innerType Exp(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.Exp)) {
			Enum.innerType it1 = Term(child.getChild(0));
			return OtherTerm(child.getChild(1), it1);
		}
		return null;
	}

	private innerType OtherTerm(TreeNode child, innerType it1) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.OtherTerm)) {
			if (child.getchildNum() > 0) {
				if (it1.equals(Exp(child.getChild(1)))) {
					return it1;
				} else {
					common.Error.setError(child.getChild(0).getChild(0)
							.getLine(), 0, 3);
					common.Error.printError("类型不相容");
				}
			} else {
				return it1;
			}
		}
		return null;
	}

	private Enum.innerType Term(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.Term)) {
			Enum.innerType it1 = Factor(child.getChild(0));
			return OtherFactor(child.getChild(1), it1);

		}
		return null;
	}

	private innerType OtherFactor(TreeNode child, innerType it1) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.OtherFactor)) {
			if (child.getchildNum() > 0) {
				if (it1.equals(Term(child.getChild(1)))) {
					return it1;
				} else {
					common.Error.setError(child.getChild(0).getChild(0)
							.getLine(), 0, 3);
					common.Error.printError("类型不相容");
				}
			} else {
				return it1;
			}
		}
		return null;
	}

	private Enum.innerType Factor(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.Factor)) {
			if (child.getChild(0).getchildNum() > 0) {
				// Variable
				return Variable(child.getChild(0));
			} else if (child.getChild(0).getTerminal()
					.equals(Enum.lexType.INTC)) {
				// INTC
				return Enum.innerType.IntType;
			} else {
				// (Exp)
				return Exp(child.getChild(1));
			}
		}
		return null;
	}

	private innerType Variable(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.Variable)) {
			BasicId bi = searchInnerType(child.getChild(0));
			if (child.getChild(1).getchildNum() == 0) {
				return bi.itype.kind;
			} else {
				return VariMore(child.getChild(1), bi);
			}
		}
		return null;
	}

	private innerType VariMore(TreeNode child, BasicId bi) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.VariMore)) {
			if (bi.kind.equals(Enum.idKind.varKind)) {
				if (child.getChild(0).getTerminal().equals(Enum.lexType.DOT)) {
					// .FieldVar
					if (bi.itype.kind.equals(Enum.innerType.RecordType)) {
						VarId vi = (VarId) bi;
						InnerRecordType irt = (InnerRecordType) vi.itype;
						for (InnerRecordType.fieldChain field : irt.body) {
							if (field.idname.equals(child.getChild(1)
									.getChild(0).getData())) {
								// 匹配到域名
								return FieldVar(child.getChild(1), vi, field);
							}
						}
						common.Error.setError(child.getChild(1).getChild(0)
								.getLine(), 0, 3);
						common.Error.printError("域名不存在");
					} else {
						common.Error
								.setError(child.getChild(0).getLine(), 0, 3);
						common.Error.printError(bi.data + "不是记录类型");
					}

				} else {
					// [Exp]
					VarId vi = (VarId) bi;
					if (bi.itype.kind.equals(Enum.innerType.ArrayType)) {
						InnerArrayType iat = (InnerArrayType) vi.itype;
						if (Exp(child.getChild(1)).equals(
								Enum.innerType.IntType)) {
							// int sub = Integer.parseInt(child.)
							// if () 数组越界处理??????????????????
							return iat.elementTy.kind;
						} else {
							common.Error.setError(child.getChild(0).getLine(),
									0, 3);
							common.Error.printError("数组下标类型错误");
						}
					} else {
						common.Error
								.setError(child.getChild(0).getLine(), 0, 3);
						common.Error.printError(bi.data + "不是数组类型");
					}

				}
			} else {
				common.Error.setError(child.getChild(0).getLine(), 0, 3);
				common.Error.printError(bi.data + "不是变量类型");
			}

		}
		return null;
	}

	private innerType FieldVar(TreeNode child, VarId vi, fieldChain field) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.FieldVar)) {
			return FieldVarMore(child.getChild(1), vi, field);
		}
		return null;

	}

	private innerType FieldVarMore(TreeNode child, VarId vi, fieldChain field) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.FieldVarMore)) {
			if (child.getchildNum() > 0) {
				if (field.unitType.kind.equals(Enum.innerType.ArrayType)) {
					InnerArrayType iat = (InnerArrayType) field.unitType;
					if (Exp(child.getChild(1)).equals(Enum.innerType.IntType)) {
						return iat.elementTy.kind;
					} else {
						common.Error
								.setError(child.getChild(0).getLine(), 0, 3);
						common.Error.printError("下标类型错误");
					}
				} else {
					common.Error.setError(child.getChild(0).getLine(), 0, 3);
					common.Error.printError(vi.data + "不是数组类型");
				}
			} else {
				return field.unitType.kind;
			}
		}
		return null;
	}

	private void DeclarePart(TreeNode root) {
		if (root.getNonTerminal().equals(Enum.nonTerminals.DeclarePart)) {
			TypeDecpart(root.getChild(0));
			VarDecpart(root.getChild(1));
			ProcDecpart(root.getChild(2));
		}
	}

	private void TypeDecpart(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.TypeDecpart)
				&& child.getchildNum() > 0) {
			TypeDec(child.getChild(0));
		}
	}

	private void TypeDec(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.TypeDec)) {
			TypeDecList(child.getChild(1));
		}
	}

	private void TypeDecList(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.TypeDecList)) {
			common.TypeId tid = new common.TypeId();
			tid.itype = TypeDef(child.getChild(2));
			tid.data = TypeId(child.getChild(0));
			tid.kind = idKind.typeKind;
			tid.line = child.getChild(1).getLine();
			// 添加记录到符号表

			Boolean b = checkBeforeAdd(tid);
			if (b) {
				idTable.add(tid);
			} else {
				common.Error.setError(tid.line, 0, 3);
				common.Error.printError("标识符" + tid.data + "重复声明 ");
			}

			TypeDecMore(child.getChild(4));
		}

	}

	

	private void TypeDecMore(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.TypeDecMore)) {
			if (child.getchildNum() > 0) {
				TypeDecList(child.getChild(0));
			}
		}
	}

	private String TypeId(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.TypeId)) {
			return child.getData();
		}
		return null;
	}

	private InnerType TypeDef(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.TypeDef)) {

			if (child.getChild(0).getchildNum() == 0) {
				// 查表得到类型.....最后做
				BasicId bi = searchInnerType(child.getChild(0));
				if (bi.kind.equals(Enum.idKind.typeKind)) {
					return bi.itype;
				} else {
					common.Error.setError(child.getLine(), 0, 3);
					common.Error
							.printError("标识符" + child.getData() + "不是一个类型 ");
				}
			} else if (child.getChild(0).getNonTerminal()
					.equals(Enum.nonTerminals.BaseType)) {
				return BaseType(child.getChild(0));
			} else if (child.getChild(0).getNonTerminal()
					.equals(Enum.nonTerminals.StructureType)) {
				return StructureType(child.getChild(0));
			}
		}
		return null;
	}
	
	
	/**
	 * 添加符号表象之前检测是否已声明过
	 * 
	 * @param tid
	 *            待插入的表项
	 * @return true 表示可以插入
	 */
	private boolean checkBeforeAdd(common.BasicId tid) {
		if (idTable.isEmpty()) {
			scopeStack.push(0);
			return true;
		} else {
			int bottom = scopeStack.peek();

			for (int i = idTable.size() - 1; i >= bottom;) {
				BasicId bi = idTable.get(i);
				if (bi.kind.equals(Enum.idKind.specKind)) {
					i = bi.line ;
					
					continue;
				} else if (bi.data.equals(tid.data)) {
					return false;
				}
				i--;
			}
		}
		return true;

	}

	/**
	 * 根据标识符的值,查询类型
	 * 
	 * @param child
	 *            根节点
	 * @return
	 */
	private BasicId searchInnerType(TreeNode child) {
		if (idTable.isEmpty()) {
			common.Error.setError(child.getLine(), 0, 3);
			common.Error.printError("标识符" + child.getData() + "未声明 ");
		} else {
			// int bottom = scopeStack.peek();

			for (int i = idTable.size() - 1; i >= 0;) {
				BasicId bi = idTable.get(i);
				if (bi.kind.equals(Enum.idKind.specKind)) {
					i = bi.line ;
					continue;
				} else if (bi.data.equals(child.getData())) {
					return bi;
				}
				i--;
			}
		}
		common.Error.setError(child.getLine(), 0, 3);
		common.Error.printError("标识符" + child.getData() + "未声明 ");
		return null;
	}

	private InnerType StructureType(TreeNode child) {

		if (child.getNonTerminal().equals(Enum.nonTerminals.StructureType)) {
			InnerType it = null;
			if (child.getChild(0).getNonTerminal()
					.equals(Enum.nonTerminals.ArrayType)) {
				it = ArrayType(child.getChild(0));
			} else {
				it = RecType(child.getChild(0));
			}
			return it;
		}

		return null;
	}

	/**
	 * 结构体类型
	 * 
	 * @param child
	 * @return
	 */
	private InnerType RecType(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.RecType)) {
			InnerRecordType irt = new InnerRecordType();
			irt.kind = Enum.innerType.RecordType;
			roff = 0;
			irt.body = new ArrayList<InnerRecordType.fieldChain>();
			FieldDecList(irt.body, child.getChild(1));
			irt.size = roff;
			return irt;
		}
		return null;
	}

	private ArrayList<fieldChain> FieldDecList(ArrayList<fieldChain> body,
			TreeNode child) {

		if (child.getNonTerminal().equals(Enum.nonTerminals.FieldDecList)) {

			// base type
			ArrayList<TreeNode> ids = new ArrayList<TreeNode>();
			IdList(ids, child.getChild(1));

			if (child.getChild(0).getNonTerminal()
					.equals(Enum.nonTerminals.BaseType)) {

				for (TreeNode node : ids) {
					// 创建filed结构
					InnerRecordType.fieldChain filed = new InnerRecordType().new fieldChain();
					filed.idname = node.getData();
					filed.offset = roff;
					filed.unitType = BaseType(child.getChild(0));
					roff += filed.unitType.size;

					body.add(filed);

				}

			} else {
				// array type
				for (TreeNode node : ids) {
					// 创建filed结构
					InnerRecordType.fieldChain filed = new InnerRecordType().new fieldChain();
					filed.idname = node.getData();
					filed.offset = roff;
					filed.unitType = ArrayType(child.getChild(0));
					roff += filed.unitType.size;

					body.add(filed);

				}
			}

			FieldDecMore(body, child.getChild(3));
		}

		return null;
	}

	private void FieldDecMore(ArrayList<fieldChain> body, TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.FieldDecMore)) {
			if (child.getchildNum() > 0) {
				FieldDecList(body, child.getChild(0));
			}
		}

	}

	private void IdList(ArrayList<TreeNode> ids, TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.IdList)) {
			ids.add(child.getChild(0));
			IdMore(ids, child.getChild(1));
		}
	}

	private void IdMore(ArrayList<TreeNode> ids, TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.IdMore)) {
			if (child.getchildNum() > 0) {
				IdList(ids, child.getChild(1));
			}
		}

	}

	private InnerType ArrayType(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.ArrayType)) {
			InnerArrayType iat = new InnerArrayType();
			iat.kind = Enum.innerType.ArrayType;
			iat.indexTy = Enum.innerType.IntType;
			iat.elementTy = BaseType(child.getChild(7));
			String low = child.getChild(2).getData();
			String top = child.getChild(4).getData();
			iat.low = Integer.parseInt(low);
			iat.up = Integer.parseInt(top);
			int len = iat.up - iat.low + 1;
			if (len <= 0) {
				common.Error.setError(child.getChild(0).getLine(), 0, 3);
				common.Error.printError("数组下表定义错误");
			} else {
				iat.size = iat.elementTy.size * len;
			}
			return iat;
		}
		return null;
	}

	private InnerType BaseType(TreeNode child) {

		if (child.getNonTerminal().equals(Enum.nonTerminals.BaseType)) {
			InnerType it = new InnerBasicType();
			it.size = 1;
			if (child.getChild(0).getTerminal().equals(Enum.lexType.INTEGER)) {
				it.kind = Enum.innerType.IntType;
			} else {
				it.kind = Enum.innerType.CharType;
			}

			return it;
		}
		return null;
	}

	/**
	 * 变量声明部分
	 * 
	 * @param child
	 */
	private void VarDecpart(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.VarDecpart)) {
			if (child.getchildNum() > 0) {
				VarDec(child.getChild(0));
			}
		}

	}

	private void VarDec(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.VarDec)) {
			VarDecList(child.getChild(1));
		}

	}

	private void VarDecList(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.VarDecList)) {
			InnerType it = TypeDef(child.getChild(0));
			ArrayList<TreeNode> idList = new ArrayList<TreeNode>();
			VarIdList(idList, child.getChild(1));

			for (TreeNode node : idList) {
				// 处理每个标识符
				VarId vi = new VarId();
				vi.kind = Enum.idKind.varKind;
				vi.data = node.getData();
				vi.itype = it;
				vi.line = child.getChild(2).getLine();
				// ???变量类型
				vi.access = Enum.accessType.dir;
				vi.level = level;
				vi.offset = offset;
				offset += it.size;
				boolean b = checkBeforeAdd(vi);
				if (b) {
					idTable.add(vi);
				} else {
					common.Error.setError(vi.line, 0, 3);
					common.Error.printError("标识符" + vi.data + "重复声明 ");
				}
			}

			VarDecMore(child.getChild(3));

		}
	}

	private void VarDecMore(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.VarDecMore)) {
			if (child.getchildNum() > 0) {
				VarDecList(child.getChild(0));
			}
		}
	}

	private void VarIdList(ArrayList<TreeNode> idList, TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.VarIdList)) {
			idList.add(child.getChild(0));
			VarIdMore(idList, child.getChild(1));
		}

	}

	private void VarIdMore(ArrayList<TreeNode> idList, TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.VarIdMore)) {
			if (child.getchildNum() > 0) {
				VarIdList(idList, child.getChild(1));
			}
		}

	}

	/**
	 * 过程声明部分
	 * 
	 * @param child
	 */
	private void ProcDecpart(TreeNode child) {

		if (child.getNonTerminal().equals(Enum.nonTerminals.ProcDecpart)) {
			if (child.getchildNum() > 0) {
				ProcDec(child.getChild(0));
			}
		}

	}

	/**
	 * 过程声明
	 * 
	 * @param child
	 */
	private void ProcDec(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.ProcDec)) {

			// 添加符号表
			ProcId pi = new ProcId();
			pi.data = ProcName(child.getChild(1));
			pi.itype = null;
			pi.kind = Enum.idKind.procKind;
			pi.level = level;
			pi.line = child.getChild(0).getLine();

			boolean b = checkBeforeAdd(pi);
			if (b) {
				ArrayList<BasicId> paramList = new ArrayList<BasicId>();
				ParamList(paramList, child.getChild(3));
				pi.paramCount = paramList.size();
				pi.paramStart = idTable.size();
				idTable.add(pi);
				// 进入新的局部化区域
				level += 1;
				offset = 0;
				scopeStack.push(idTable.size()-1);

				for (BasicId bi : paramList) {
					if (checkBeforeAdd(bi)) {
						idTable.add(bi);
					} else {
						common.Error.setError(bi.line, 0, 3);
						common.Error.printError(" 标识符" + bi.data + "重复声明");
					}
				}

			} else {
				common.Error.setError(pi.line, 0, 3);
				common.Error.printError(" 标识符" + pi.data + "重复声明");
			}

			// 过程嵌套定义
			ProcDecPart(child.getChild(6));
			ProcBody(child.getChild(7));
			ProcDecMore(child.getChild(8));

		}
	}

	private void ProcDecPart(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.ProcDecPart)) {
			DeclarePart(child.getChild(0));
		}
	}

	/**
	 * 过程体
	 * 
	 * @param child
	 */
	private void ProcBody(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.ProcBody)) {
			ProgramBody(child.getChild(0));
		}
	}

	private void ProcDecMore(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.ProcDecMore)) {
			if (child.getchildNum() > 0) {
				ProcDec(child.getChild(0));
			}
		}
	}

	private void ParamList(ArrayList<BasicId> paramList, TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.ParamList)) {
			if (child.getchildNum() > 0) {
				ParamDecList(paramList, child.getChild(0));
			}
		}

	}

	private void ParamDecList(ArrayList<BasicId> paramList, TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.ParamDecList)) {
			Param(paramList, child.getChild(0));
			ParamMore(paramList, child.getChild(1));
		}

	}

	private void ParamMore(ArrayList<BasicId> paramList, TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.ParamMore)) {
			if (child.getchildNum() > 0) {
				ParamDecList(paramList, child.getChild(1));
			}
		}
	}

	private void Param(ArrayList<BasicId> paramList, TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.Param)) {
			if (child.getChild(0).getchildNum() > 0) {
				// 直接参数
				InnerType it = TypeDef(child.getChild(0));
				ArrayList<TreeNode> paramIds = new ArrayList<TreeNode>();
				FormList(paramIds, child.getChild(1));
				for (TreeNode node : paramIds) {
					VarId vi = new VarId();
					vi.kind = Enum.idKind.varKind;
					vi.access = Enum.accessType.dir;
					vi.data = node.getData();
					vi.itype = it;
					vi.line = node.getLine();
					vi.level = level;
					vi.offset = offset;
					offset += it.size;
					paramList.add(vi);
				}

			} else {
				// 间接参数
				InnerType it = TypeDef(child.getChild(1));
				ArrayList<TreeNode> paramIds = new ArrayList<TreeNode>();
				FormList(paramIds, child.getChild(2));
				for (TreeNode node : paramIds) {
					VarId vi = new VarId();
					vi.kind = Enum.idKind.varKind;
					vi.access = Enum.accessType.indir;
					vi.data = node.getData();
					vi.itype = it;
					vi.line = node.getLine();
					vi.level = level;
					vi.offset = offset;
					offset += it.size;
					paramList.add(vi);
				}
			}
		}
	}

	private void FormList(ArrayList<TreeNode> paramIds, TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.FormList)) {
			paramIds.add(child.getChild(0));
			FidMore(paramIds, child.getChild(1));
		}

	}

	private void FidMore(ArrayList<TreeNode> paramIds, TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.FidMore)) {
			if (child.getchildNum() > 0) {
				FormList(paramIds, child.getChild(1));
			}
		}
	}

	private String ProcName(TreeNode child) {
		if (child.getNonTerminal().equals(Enum.nonTerminals.ProcName)) {
			return child.getChild(0).getData();
		}
		return null;
	}

	public String getStringIdTable() {
		String s = "";
		for (int i=0; i < idTable.size(); i++) {
//		for (BasicId bi : idTable) {
			BasicId bi = idTable.get(i);
			if (bi.kind.equals(Enum.idKind.typeKind)) {
				common.TypeId ti = (common.TypeId) bi;
				System.out.println("index:"+i+"\t"+ti.data + "====" + ti.itype.kind + " size="
						+ ti.itype.size);

				s += "index:"+i+"\t"+"name:" + ti.data + "\tkind:" + ti.kind + "\ttype:"
						+ ti.itype.toString() + "\n";
			} else if (bi.kind.equals(Enum.idKind.varKind)) {
				common.VarId vi = (common.VarId) bi;
				// System.out.println(vi.data + "====" + vi.itype.kind
				// + "  sizeoftype=" + vi.itype.size + "  level="
				// + vi.level + "  offset=" + vi.offset);
				s += "index:"+i+"\t"+"name:" + vi.data + "\tkind:" + vi.kind + "\tlevel:"
						+ vi.level + "\toffset:" + vi.offset + "\taccess:"
						+ vi.access + "\ttype:" + vi.itype.toString() + "\n";
			} else if (bi.kind.equals(Enum.idKind.procKind)) {
				common.ProcId pid = (ProcId) bi;
				s += "index:"+i+"\t"+"name:" + pid.data + "\tkind:" + pid.kind + "\tlevel:"
						+ pid.level + "\ttype:" + pid.itype + "\tparamCount:"
						+ pid.paramCount + "\tparamStart:" + pid.paramStart+1
						+ "\n";
			} else {
				common.SpecId sid = (SpecId) bi;
				s += "index:"+i+"\t"+"name:" + sid.data + "\tpoint:" + sid.line + "\n";
			}
		}
		return s;
	}

	public static void main(String[] args) {

		try {
			// 获取工程的路径
			String path = System.getProperty("user.dir");
			path = path.replace("\\", "/");
			// System.out.println(path);
			TreeNode root = new TreeNode();

			Parser parser = new Parser();
			root = parser.getTree1(path + "/src/c11.snl");

			SemanticAnalysis sa = new SemanticAnalysis();

			sa.Program(root);

			System.out.println("恭喜!您的程序无语义错误!");

			/*
			 * for (BasicId bi : sa.idTable) { if
			 * (bi.kind.equals(Enum.idKind.typeKind)) { common.TypeId ti =
			 * (common.TypeId) bi; System.out.println(ti.data + "====" +
			 * ti.itype.kind + " size=" + ti.itype.size); } else if
			 * (bi.kind.equals(Enum.idKind.varKind)) { common.VarId vi =
			 * (common.VarId) bi; System.out.println(vi.data + "====" +
			 * vi.itype.kind + "  sizeoftype=" + vi.itype.size + "  level=" +
			 * vi.level + "  offset=" + vi.offset); } }
			 */

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
